home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
201-225
/
disk_203
/
gurusguide
/
serial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
6KB
|
201 lines
/************************************************************************
********** **********
********** S E R I A L I N T E R R U P T **********
********** ------------------------------- **********
********** **********
********** Copyright (C) 1988 Sassenrath Research **********
********** All Rights Reserved. **********
********** **********
********** Example from the "Guru's Guide, Meditation #1" **********
********** **********
*************************************************************************
** **
** - NOTICE - **
** **
** The "Guru's Guide, Meditation #1" contains detailed information **
** about Amiga interrupts as well as a complete discussion of this **
** and other examples. Meditation #1 and all of its examples were **
** written by Carl Sassenrath, the architect of Amiga's multitasking **
** operating system. Copies of the "Guru's Guide" may be obtained **
** from: **
** GURU'S GUIDE, P.O. BOX 1510, UKIAH, CA 95482 **
** **
** Please include a check for $14.95, plus $1.50 shipping ($4.00 if **
** outside North America). CA residents add 6% sales tax. **
** **
** This example may be used for any purposes, commercial, personal, **
** public, and private, so long as ALL of the above text, copyright, **
** mailing address, and this notice are retained in their entirety. **
** **
** THIS EXAMPLE IS PROVIDED WITHOUT WARRANTY OF ANY KIND. **
** **
************************************************************************/
/*
** IMPORTANT WARNING:
**
** This program will interfere with the proper operation of the Amiga's
** Serial Device Driver. Use with care.
*/
/*
** COMPILATION NOTE:
**
** Compiled under MANX AZTEC C 3.6A. Use the +L compiler option
** and the "c32" library. Link with intrsup.o.
*/
#include <exec/exec.h>
#include <hardware/intbits.h>
#include <hardware/custom.h>
#include <stdio.h>
#define TIMEOUT 240 /* 4 seconds */
#define BAUD_RATE 372 /* 9600 baud */
char IntrName[] = "serial.example";
struct SigInfo
{
short buffer; /* char buffer */
short intrmask; /* intr to reset */
long signal; /* signal mask */
struct Task *task; /* task to signal */
long sig; /* sig bit to free */
struct Interrupt *intr;
} Serial, TimeOut;
/* Interrupt Processing Code */
VOID SerialCode();
VOID TimeOutCode();
#asm
TIMEOUT equ 240
EXECBASE equ 4
intreq EQU $9C ; interrupt request
serdatr EQU $18 ; serial data read
public _LVOSignal
_TimeOutCode:
subq.w #1,(a1) ; decr timeout
move.w (a1),d0
bge.s exit ; expired?
move.w #TIMEOUT,(a1) ; reset timeout
addq.l #4,a1 ; adjust pointer
bra.s signal
_SerialCode:
move.w serdatr(a0),(a1)+ ; get the char
move.w (a1)+,intreq(a0) ; clear the request
signal:
move.l (a1)+,d0 ; the signal
move.l (a1)+,a1 ; the task
move.l EXECBASE,a6
jsr _LVOSignal(a6)
exit:
moveq #0,d0 ; Z-flag - do next server
rts
#endasm
main()
{
extern long Wait();
extern int Enable_Abort;
long waitsigs;
char c;
Enable_Abort = 0; /* prevent a CTRL-C */
/* Required for proper clean-up: */
Serial.sig = TimeOut.sig = -1;
MakeSigIntr(IntrName,INTB_RBF,0,&SerialCode,&Serial);
MakeSigIntr(IntrName,INTB_VERTB,-60,&TimeOutCode,&TimeOut);
/* Set serial baud rate to 9600 */
custom.serper = BAUD_RATE;
AddHandler(INTB_RBF,Serial.intr);
EnableIntr(INTB_RBF);
TimeOut.buffer = TIMEOUT;
AddIntServer(INTB_VERTB,TimeOut.intr);
while (TRUE)
{
waitsigs = Wait(Serial.signal | TimeOut.signal);
if (waitsigs & Serial.signal)
{
c = (char)Serial.buffer;
if (c == 3) break; /* CTRL-C to stop */
if (c == 13) c = 10; /* change CR to LF */
putchar(c);
fflush(stdout); /* force it out */
/* Reset timeout */
TimeOut.buffer = TIMEOUT;
}
if (waitsigs & TimeOut.signal)
puts("\nTIMEOUT!");
}
DisableIntr(INTB_RBF);
MainExit(0);
}
MakeSigIntr(iname,ibit,pri,iproc,isig)
char *iname;
int ibit;
VOID (*iproc)();
register struct SigInfo *isig;
{
extern struct Task *FindTask();
extern struct Interrupt *MakeIntr();
struct Interrupt *intr;
isig->sig = AllocSignal(-1);
if (isig->sig == -1) MainExit(100);
intr = MakeIntr(iname,pri,iproc,isig);
if (intr == NULL) MainExit(101);
isig->buffer = 0;
isig->intrmask = 1 << ibit;
isig->signal = 1 << isig->sig;
isig->task = FindTask(NULL);
isig->intr = intr;
}
MainExit(error)
int error;
{
puts("Terminate!");
if (Serial.intr != NULL)
{
RemHandler(INTB_RBF, Serial.intr);
FreeIntr(Serial.intr);
}
if (TimeOut.intr != NULL)
{
RemIntServer(INTB_VERTB, TimeOut.intr);
FreeIntr(TimeOut.intr);
}
if (Serial.sig != -1) FreeSignal(Serial.sig);
if (TimeOut.sig != -1) FreeSignal(TimeOut.sig);
exit(error);
}